﻿using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Antu.WebControls.Design;

namespace Antu.WebControls
{
    /// <summary>
    /// Tab选项卡控件(缺少样式 需要自定义)
    /// </summary>
    [ParseChildren(true, "TabPages")]
    [Description("Antu.WebControls.TabControl")]
    [ToolboxData("<{0}:TabControl runat=server></{0}:TabControl>")]
    [DefaultEvent("SelectedIndexChanged")]
    [DesignTimeVisible(true)]
    [PersistChildren(false)]
    [Designer(typeof(TabControlDesigner))]
    public class TabControl : WebControl, IPostBackDataHandler, INamingContainer, IPostBackEventHandler
    {
        private int _SelectedIndex;
        private TabSelectionMode _SelectionMode;
        private HtmlInputHidden hhdSelectedTab;

        //private Style _
        /// <summary>
        /// 当前选定的选项卡页的索引改变事件
        /// </summary>
        public event EventHandler SelectedIndexChanged;

        /// <summary>
        /// 选项卡控件中选项卡页的集合
        /// </summary>
        [MergableProperty(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
        public TabPageCollection TabPages
        {
            get
            {
                return (TabPageCollection)this.Controls;
            }
        }

        /// <summary>
        /// 当前选定的选项卡页的索引
        /// </summary>
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public int SelectedIndex
        {
            get
            {
                if (TabPages.Count <= 0)
                {
                    _SelectedIndex = -1;
                }
                else
                {
                    if (_SelectedIndex == -1)
                    {
                        _SelectedIndex = 0;
                        for (int i = 0; i < this.TabPages.Count; i++)
                        {
                            if (this.TabPages[i].Visible && (this.TabPages[i].UniqueID == this.SelectedTabId))
                            {
                                _SelectedIndex = i;
                                break;
                            }
                        }
                    }
                    if (_SelectedIndex >= TabPages.Count)
                    {
                        _SelectedIndex = 0;
                    }
                }
                return _SelectedIndex;
            }
            set
            {
                if (value < -1)
                {
                    _SelectedIndex = -1;
                }
                else if (value >= this.TabPages.Count)
                {
                    _SelectedIndex = this.TabPages.Count - 1;
                }
                else
                {
                    _SelectedIndex = value;
                }
            }
        }

        /// <summary>
        /// 当前选定的选项卡页的Id
        /// </summary>
        protected string SelectedTabId
        {
            get
            {
                if (this.ViewState["SelectedTabId"] != null)
                {
                    return (string)this.ViewState["SelectedTabId"];
                }
                return string.Empty;
            }
            set
            {
                this.ViewState["SelectedTabId"] = value;
            }
        }

        /// <summary>
        /// Tab页的切换方式
        /// </summary>
        public TabSelectionMode SelectionMode
        {
            get
            {
                return this._SelectionMode;
            }
            set
            {
                this._SelectionMode = value;
            }
        }

        /// <summary>
        /// 获取或设置由 Web 服务器控件在客户端呈现的级联样式表 (CSS) 类
        /// </summary>
        /// <value>由 Web 服务器控件在客户端呈现的 CSS 类。默认为 "TabControl"。</value>
        [DefaultValueAttribute("TabControl")]
        public override string CssClass
        {
            get
            {
                if (string.IsNullOrEmpty(base.CssClass))
                {
                    base.CssClass = "TabControl";
                }
                return base.CssClass;
            }
            set
            {
                base.CssClass = value;
            }
        }

        private string _TabPageClass;
        /// <summary>
        /// 获取或设置Tab页面的CssClass类名
        /// </summary>
        /// <value>默认为 "tab-page"</value>
        [DefaultValueAttribute("tab-page")]
        [Category("样式")]
        [Description("获取或设置Tab页面的CssClass类名")]
        public string TabPageClass
        {
            get
            {
                if (string.IsNullOrEmpty(_TabPageClass))
                {
                    _TabPageClass = "tab-page";
                }
                return _TabPageClass;
            }
            set { _TabPageClass = value; }
        }

        private string _TabClass;
        /// <summary>
        /// 获取或设置Tab标签的CssClass类名(选择状态为tab.selected,悬浮状态为tab.hover)
        /// </summary>
        ///<value>默认为 "tab"</value>
        [DefaultValueAttribute("tab")]
        [Category("样式")]
        [Description("获取或设置Tab标签的CssClass类名(选择状态为tab.selected,悬浮状态为tab.hover)")]
        public string TabClass
        {
            get
            {
                if (string.IsNullOrEmpty(_TabClass))
                {
                    _TabClass = "tab";
                }
                return _TabClass;
            }
            set { _TabClass = value; }
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        public TabControl()
        {
            this.hhdSelectedTab = new HtmlInputHidden();
            this._SelectedIndex = -1;
            this.hhdSelectedTab.Value = string.Empty;
            this._SelectionMode = TabSelectionMode.Client;
            this.Height = (Unit)400;
            this.Width = (Unit)350;
        }

        /// <summary>
        /// 创建一个新的 <see cref="T:System.Web.UI.ControlCollection"></see> 对象来保存服务器控件的子控件（包括文本控件和服务器控件）。
        /// </summary>
        /// <returns>
        /// 包含当前服务器控件的子服务器控件的 <see cref="T:System.Web.UI.ControlCollection"></see> 对象。
        /// </returns>
        protected override ControlCollection CreateControlCollection()
        {
            return new TabPageCollection(this);
        }

        /// <summary>
        /// 由 ASP.NET 页面框架调用，以通知使用基于合成的实现的服务器控件创建它们包含的任何子控件，以便为回发或呈现做准备。
        /// </summary>
        protected override void CreateChildControls()
        {
            this.hhdSelectedTab.ID = this.UniqueID;
            base.CreateChildControls();
        }

        /// <summary>
        /// 引发 PreRender 事件
        /// </summary>
        /// <param name="e">包含事件数据的 EventArgs 对象</param>
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            this.Page.ClientScript.RegisterClientScriptResource(typeof(TabControl), "Antu.WebControls.TabControl.TabControl.js");

            int index = this.SelectedIndex;
            if (index != -1)
            {
                this.TabPages[index].Selected = true;
                this.hhdSelectedTab.Value = this.TabPages[index].UniqueID;
            }
            else
            {
                this.hhdSelectedTab.Value = string.Empty;
            }
        }

        /// <summary>
        /// 引发 SelectedIndexChanged 事件
        /// </summary>
        /// <param name="e">包含事件数据的 EventArgs 对象</param>
        protected void OnSelectedIndexChanged(EventArgs e)
        {
            EventHandler temp = SelectedIndexChanged;
            if (temp != null)
            {
                temp(this, e);
            }
        }

        /// <summary>
        /// 将服务器控件内容发送到提供的 HtmlTextWriter 对象，此对象编写将在客户端呈现的内容
        /// </summary>
        /// <param name="writer">接收服务器控件内容的 HtmlTextWriter 对象</param>

        protected override void Render(HtmlTextWriter writer)
        {
            writer.AddAttribute(HtmlTextWriterAttribute.Style, GetControlStyle(base.Style));
            writer.AddAttribute(HtmlTextWriterAttribute.Id, this.UniqueID + "_Tab");
            writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass);
            writer.RenderBeginTag(HtmlTextWriterTag.Div);
            this.hhdSelectedTab.RenderControl(writer);

            writer.RenderBeginTag(HtmlTextWriterTag.Div);
            this.RenderTabButton(writer);
            writer.RenderEndTag();

            writer.RenderBeginTag(HtmlTextWriterTag.Div);
            this.RenderTabContent(writer);
            writer.RenderEndTag();

            writer.RenderEndTag();
        }

        /// <summary>
        /// 呈现Tab标签
        /// </summary>
        /// <param name="writer">接收服务器控件内容的 HtmlTextWriter 对象</param>
        private void RenderTabButton(HtmlTextWriter writer)
        {
            for (int i = 0; i < this.TabPages.Count; i++)
            {
                if (this.TabPages[i].Selected)
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.TabClass + " selected");
                }
                else
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.TabClass);
                    if (this.SelectionMode == TabSelectionMode.Server)
                    {
                        writer.AddAttribute(HtmlTextWriterAttribute.Onclick, "Tab_OnSelectServerClick(this,'" + this.TabPages[i].UniqueID + "');"
                                                    + this.Page.ClientScript.GetPostBackEventReference(this, ""));
                    }
                }
                if (this.SelectionMode == TabSelectionMode.Client)
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Onclick, "Tab_OnSelectClientClick(this,'" + this.TabPages[i].UniqueID + "','" + this.TabClass + "')");
                }
                writer.AddAttribute(HtmlTextWriterAttribute.Id, this.TabPages[i].UniqueID + "_Title");
                writer.AddAttribute("onmouseover", "Tab_OnMouseOver(this,'" + this.TabClass + "')");
                writer.AddAttribute("onmouseout", "Tab_OnMouseOut(this,'" + this.TabClass + "')");
                writer.RenderBeginTag(HtmlTextWriterTag.Span);
                writer.Write(this.TabPages[i].Caption);
                writer.RenderEndTag();
            }
        }

        /// <summary>
        /// 呈现Tab页
        /// </summary>
        /// <param name="writer">接收服务器控件内容的 HtmlTextWriter 对象</param>
        private void RenderTabContent(HtmlTextWriter writer)
        {
            for (int i = 0; i < this.TabPages.Count; i++)
            {
                this.TabPages[i].RenderControl(writer);
            }
        }

        /// <summary>
        /// 获取控件的样式
        /// </summary>
        /// <param name="style">样式</param>
        /// <returns>style字符串</returns>

        internal static string GetControlStyle(CssStyleCollection style)
        {
            string str = string.Empty;
            foreach (string aKey in style.Keys)
            {
                str = string.Concat(new string[] { str, aKey, ":", style[aKey], ";" });
            }
            return str;
        }

        #region IPostBackDataHandler 成员

        /// <summary>
        /// 处理回发数据
        /// </summary>
        /// <param name="postDataKey">控件的主要标识符</param>
        /// <param name="postCollection">所有传入名称值的集合</param>
        /// <returns>如果服务器控件的状态由于回发而发生更改，则为 true；否则为 false</returns>
        /// <!--
        /// 创建人  : LiKun
        /// 创建时间: 2006-09-12
        /// -->
        public bool LoadPostData(string postDataKey, NameValueCollection postCollection)
        {
            if (postCollection != null)
            {
                string text1 = postCollection[postDataKey];
                if ((text1 != null) && (text1 != this.SelectedTabId))
                {
                    this.SelectedTabId = text1;
                    return true;
                }
                this.SelectedTabId = text1;
            }
            return false;
        }

        /// <summary>
        /// 用信号要求服务器控件对象通知 ASP.NET 应用程序该控件的状态已更改
        /// </summary>
        /// <!--
        /// 创建人  : LiKun
        /// 创建时间: 2006-09-12
        /// -->
        public void RaisePostDataChangedEvent()
        {
            OnSelectedIndexChanged(EventArgs.Empty);
        }

        #endregion

        #region IPostBackEventHandler 成员

        /// <summary>
        /// 使服务器控件能够处理将窗体发送到服务器时引发的事件
        /// </summary>
        /// <param name="eventArgument">要传递到事件处理程序的可选事件参数</param>
        /// <!--
        /// 创建人  : LiKun
        /// 创建时间: 2006-09-12
        /// -->
        public void RaisePostBackEvent(string eventArgument)
        {
        }

        #endregion

        /// <summary>
        /// Tab页的切换方式
        /// </summary>
        public enum TabSelectionMode
        {
            /// <summary>
            /// 客户端
            /// </summary>
            Client,

            /// <summary>
            /// 服务器端
            /// </summary>
            Server
        }


    }
}
